import Vue from 'vue'
import App from './App.vue'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import router from "./router";
import routemap from "./assets/js/routemap"
import store from "./store"
import Vuex from 'vuex';
import jquery from 'jquery'

import { autoToolTip } from "./assets/js/echarts_auto_tooltip.js"
import Notification from "./common/notification"
import tip from "./common/tip"
import dataV from '@jiaminghi/data-view'

//https://www.cnblogs.com/cqiong/p/13813728.html
//http://datav.jiaminghi.com/guide
Vue.use(dataV)

//https://blog.csdn.net/weixin_43272781/article/details/107881057
// npm install element-resize-detector
// import ElementResizeDetectorMaker from "element-resize-detector"
// Vue.prototype.$erd = ElementResizeDetectorMaker()
//第三步：使用
// this.$erd.listenTo(document.getElementById("chinaMapChart"), (element)=>{
//   this.resize()
// })
// 如果不使用Lambda表达式作为监听器，会出现不能获取data和methods的情况，
// 具体原因参考JavaScript高级教程

// let that = this;
// this.$erd.listenTo(document.getElementById("bar"), function (element) {
//     that.$nextTick(function () {
//         //使echarts尺寸重置
//         that.myEcharts.resize();//监听元素变化
//     })
// })
//             

 Vue.prototype.$autoToolTip = autoToolTip

 Vue.prototype.$Notification = Notification

 Vue.prototype.$tip = tip


//不明白为什么不直接调用 sessionStorage.setItem(k, val);
Vue.prototype.resetSetItem = function (key, newVal) {
  if (key === 'push') {

    // 创建一个StorageEvent事件
    var newStorageEvent = document.createEvent('StorageEvent');
    const storage = {
      setItem: function (k, val) {
        sessionStorage.setItem(k, val);

        // 初始化创建的事件
        newStorageEvent.initStorageEvent('setItem', false, false, k, null, val, null, null);

        // 派发对象
        window.dispatchEvent(newStorageEvent)
      }
    }
    return storage.setItem(key, newVal);
  }
}


Vue.config.productionTip = false

//把jquery连接到原型
Vue.prototype.$ = jquery

Vue.use(ElementUI)

Vue.use(Vuex)

// 引入echarts
import echarts from 'echarts'
Vue.prototype.$echarts = echarts

//引入axios
import http from './utils/http'
Vue.prototype.$http = http

//不知道做什么的
// import request from './utils/request'
// Vue.prototype.$request = request

router.beforeEach(async (to, from, next) => {
  //验证token
  let token = sessionStorage.getItem('token')//sessionStorage页面关闭就没了
  if (token) {
    if (to.path === '/login') {
      next({ path: '/' })
    } else {
      // console.log(JSON.stringify(store.state.userRoutes));
      if (store.state.userRoutes.length === 0) {//  刷新会进入
        let userRoutes = await store.dispatch("getMenu");  
        if (userRoutes.code == 0) {
          userRoutes.data.b.map((item) => {
            item.component = "";
            item.path = "";
            item.name = "";
            item.hiden = false;
          });
          userRoutes.data.b.map((item) => {
            for (let i in item) {
              if (i == "name") {
                item[i] = item.resKey;
              }
              if (i == "path") {
                item[i] = "/" + item.resKey;
              }
              if (i == "component") {
                item[i] = item.resKey;
              }
            }
          });
          let newRoutes = userRoutes.data.b.filter((item) => item.parentId); //取出子页
          let userRoute = routemap.getRouterList(newRoutes);
          router.addRoutes(userRoute.concat({
            path: "*",
            redirect: "/404",
            hidden: true,
            component: () => import('@/views/Notfound/404')
          }))
        }

        //https://blog.csdn.net/qq_41912398/article/details/109231418
        //但是在看别的项目时常常能看到next('/logon') 、 next(to) 或者 next({ ...to, replace: true }) 这又是啥意思呢
        //其实在路由守卫中，只有next()是放行，其他的诸如：next('/logon') 、 next(to) 或者 next({ ...to, replace: true })都不是放行，而是：中断当前导航，执行新的导航

        // 注意：重点就在这，next('/logon')不是说直接去/logon路由，而是中断
        // （不是CPU的那个中断！VUE中的中断就是此时不会执行router.afterEach(() => {}）
        // 这一次路由守卫的操作，又进入一次路由守卫，就像嵌套一样，一层路由守卫，
        // 然后又是一层路由守卫，此时路由守卫进入到第二层时，to.path已经不是/home了，这个时候才执行next()放行操作。

        // 正以为如此很多人在使用动态添加路由addRoutes()会遇到下面的情况：
        // 在addRoutes()之后第一次访问被添加的路由会白屏，这是因为刚刚addRoutes()就立刻访问被添加的路由，
        // 然而此时addRoutes()没有执行结束，因而找不到刚刚被添加的路由导致白屏。因此需要从新访问一次路由才行。


        // 该如何解决这个问题 ?
        // 此时就要使用next({ ...to, replace: true })来确保addRoutes()时动态添加的路由已经被完全加载上去。

        // next({ ...to, replace: true })中的replace: true只是一个设置信息，告诉VUE本次操作后，不能通过浏览器后退按钮，返回前一个路由。

        // 因此next({ ...to, replace: true })可以写成next({ ...to })，不过你应该不希望用户在addRoutes()还没有完成的时候，可以点击浏览器回退按钮搞事情吧。

        // 其实next({ ...to })的执行很简单，它会判断：

        // 如果参数to不能找到对应的路由的话，就再执行一次beforeEach((to, from, next)直到其中的next({ ...to})能找到对应的路由为止。

        // 也就是说此时addRoutes()已经完成啦，找到对应的路由之后，接下来将执行前往对应路由的beforeEach((to, from, next) ，因此需要用代码来判断这一次是否就是前往对应路由的beforeEach((to, from, next)，如果是，就执行next()放行。

        // 如果守卫中没有正确的放行出口的话，会一直next({ ...to})进入死循环 !!!

        // 因此你还需要确保在当addRoutes()已经完成时，所执行到的这一次beforeEach((to, from, next)中有一个正确的next()方向出口。


        next({ ...to, replace: true });
      }
      else {
        next();
      }
    }
  } else {
    if (to.path !== "/login") {
      next({
        path: "/login",
      });
    }
    else {
      next()
    }
  }
});




//因此想实现动态添加路由的操作的话，代码应该是这样的：
// router.beforeEach((to, from, next) => {
//   const token = sessionStorage.getItem('access_token')
//   // 存在 token 说明已经登录
//   if (token) {
//     // 登录过就不能访问登录界面，需要中断这一次路由守卫，执行下一次路由守卫，并且下一次守卫的to是主页'
//     if (to.path === '/login') {
//       next({ path: '/' })
//     }
//     // 保存在store中路由不为空则放行 (如果执行了刷新操作，则 store 里的路由为空，此时需要重新添加路由)
//     if (store.getters.getRoutes.length || to.name != null) {
//       //放行
//       next()
//     } else {
//       // 将路由添加到 store 中，用来标记已添加动态路由
//       store.commit('ADD_ROUTER', '需要添加的路由')
//       router.addRoutes('需要添加的路由')
//       // 如果 addRoutes 并未完成，路由守卫会一层一层的执行执行，直到 addRoutes 完成，找到对应的路由
//       next({ ...to, replace: true })
//     }
//   } else {
//     // 未登录时，注意 ：在这里也许你的项目不只有 logon 不需要登录 ，register 等其他不需要登录的页面也需要处理
//     if (to.path !== '/logon') {
//       next({ path: '/logon' })
//     } else {
//       next()
//     }
//   }
 

new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app')
